//
//  CWUserAccountViewModel.swift
//  新浪微博练习02
//
//  Created by 曹魏 on 16/10/4.
//  Copyright © 2016年 itcast. All rights reserved.
//

import UIKit
private let path = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last! as NSString).appendingPathComponent("account.plist")
//有且只能够有一个处于登录状态
class CWUserAccountViewModel: NSObject {
    //单例对象
    static let sharedAccountViewModel : CWUserAccountViewModel = CWUserAccountViewModel()
    
    /*
     赋值有两种情况
     1. 用户未登陆 -> 输入用户名,密码 -> 授权 -> 截取code -> code 换token, 获取用户信息 -> 给用户信息赋值
     2. 用户已经登陆,第二次打开应用的时候 -> 从沙盒中获取用户信息  -> 给 userAccount赋值
     */
    
    var userAccount : CWUserAccount? {
        didSet {
            //一旦外界给userAccount 赋值的时候就立即给iconURL 赋值,就能够确保iconURL一定有值
            let urlString = userAccount?.avatar_large ?? ""
            iconURL = URL(string: urlString)
        }
    }
    
    
    
    //判断用户是否登录
    var userLogin : Bool {
        if userAccount?.access_token != nil && isExpires == false {
            
            return true
        }
        return false
    }
    //可以使用计算性属性 计算型属性的特点是相当于一个方法 每次执行都会调用 消耗cpu  值如果需要一直变化 就需要使用计算型属性
    //存储型的属性 调用存储型的属性的时候 实际上回直接读取内存 不消耗cpu 但是消耗内存 值一旦设置就不需要变化 就可以使用 存储型属性
    var iconURL: URL?
    //判断用户token是否过期
    var isExpires : Bool {
        if userAccount?.expires_date?.compare(Date()) == ComparisonResult.orderedDescending {
            //没有过期
            return false
        }
        //默认过期
        return true
    }
    override init() {
        super.init()
        //从沙盒中获取数据保存到单例模型中
        //在构造函数中给属性赋值 不会执行到 didSet
        self.userAccount = self.loadUserAccount()
        
        let urlString = userAccount?.avatar_large ?? ""
        iconURL = URL(string: urlString)
    }
    
    
    internal func loadAccessToken(code : String,finished : @escaping (Bool) -> ()) {
        let urlString = "https://api.weibo.com/oauth2/access_token"
        let parameters = ["client_id" : client_id,"client_secret" : client_secret,"grant_type" : "authorization_code","code" : code,"redirect_uri" : redirect_uri]
        //利用网络请求框架请求接口
        HMNetworkTools.sharedTools.request(method: .POST, urlString: urlString, parameters: parameters) { (responseObject, error) in
            
            if error != nil {
                //统一输出
                finished(false)
                return
            }
            //请求成功
            print(responseObject)
            
            
            
            //请求用户信息,实际上就是在一个网络请求的回调中发起另一个网络请求
            self.loadUserInfo(dict: responseObject as! [String : Any],finished : finished)
        }
        
        
    }
    private func loadUserInfo(dict : [String : Any],finished : @escaping (Bool) -> ()) {
        let urlString = "https://api.weibo.com/2/users/show.json"
        let access_token = dict["access_token"]!
        let uid = dict["uid"]!
        let parameters = ["access_token" : access_token,"uid" : uid]
        HMNetworkTools.sharedTools.request(method: .GET, urlString: urlString, parameters: parameters) { (responseObject, error) in
            if error != nil{
                //统一输出
                finished(false)
                return
            }
            //请求成功
            //获取用户信息成功,将字典类型的用户信息转换成模型数据存储在本地(归档)
            //1.字典转模型
            var userInfoDict = responseObject as! [String : Any]
            //2.合并字典
            for keyValues in dict {
                userInfoDict[keyValues.key] = keyValues.value
            }
            //3.字典转模型
            let userAccount = CWUserAccount(dict: userInfoDict)
            print(userAccount)
            
            
            
            //将用户模型数据存在本地
            self.saveUserAccount(userAccount: userAccount)
            //
            self.userAccount = userAccount
            finished(true)
            
        }
        
        
        
        
        
        
    }
    //通过归档的方式存储数据
    private func saveUserAccount(userAccount : CWUserAccount) {
        //路径一般为沙盒的document目录下
//        let path = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last! as NSString).appendingPathComponent("account.plist")
        //将某一对象归档到某一路径下
        NSKeyedArchiver.archiveRootObject(userAccount, toFile: path)
        //打印存储路径
        print(path)
        
    }
    //从沙盒中加载用户信息
    func loadUserAccount() -> CWUserAccount? {
        let userAccount = NSKeyedUnarchiver.unarchiveObject(withFile: path) as? CWUserAccount
        return userAccount
        
    }

    
    

}
